﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Xml.Serialization;
using Pospa.NET.WebPageTestApi.Interfaces;

namespace Pospa.NET.WebPageTestApi.DataObjects
{
	[Serializable]
	[XmlRoot("response")]
	public class TestResult : BaseTestResponse, ITestResult
	{
		private const string HumanLikeDateTimeFormat = "ddd, dd MMM yyyy HH:mm:ss +0000";

		[XmlIgnore]
		public string TestId
		{
			get { return Data.TestId; }
		}

		[XmlIgnore]
		public string SummaryUrl
		{
			get { return Data.SummaryUrl; }
		}

		[XmlIgnore]
		public string TestUrl
		{
			get { return Data.TestUrl; }
		}

		[XmlIgnore]
		public string Location
		{
			get { return Data.Location; }
		}

		[XmlIgnore]
		public string Connectivity
		{
			get { return Data.Connectivity; }
		}

		[XmlIgnore]
		public int BwDown
		{
			get { return Data.BwDown; }
		}

		[XmlIgnore]
		public int BwUp
		{
			get { return Data.BwUp; }
		}

		[XmlIgnore]
		public int Latency
		{
			get { return Data.Latency; }
		}

		[XmlIgnore]
		public int Plr
		{
			get { return Data.Plr; }
		}

		[XmlIgnore]
		public DateTime Completed
		{
			get { return DateTime.ParseExact(Data.Completed, HumanLikeDateTimeFormat, CultureInfo.InvariantCulture.DateTimeFormat); }
		}

		[XmlIgnore]
		public int Runs
		{
			get { return Data.Runs; }
		}

		[XmlIgnore]
		public int SuccessfulFVRuns
		{
			get { return Data.SuccessfulFVRuns; }
		}

		[XmlIgnore]
		public int SuccessfulRVRuns
		{
			get { return Data.SuccessfulRVRuns; }
		}

		[XmlIgnore]
		public IBaseTestResultBlock Average
		{
			get { return Data.Average; }
		}

		[XmlIgnore]
		public IEnumerable<ITestResultBlock> Results
		{
			get { return Data.TestResultSets; }
		}

		[XmlElement("data")]
		public TestResultData Data { get; set; }
	}

	[Serializable]
	[XmlRoot("data")]
	public class TestResultData
	{
		[XmlElement("testId")]
		public string TestId { get; set; }

		[XmlElement("summary")]
		public string SummaryUrl { get; set; }

		[XmlElement("testUrl")]
		public string TestUrl { get; set; }

		[XmlElement("location")]
		public string Location { get; set; }

		[XmlElement("connectivity")]
		public string Connectivity { get; set; }

		[XmlElement("bwDown")]
		public int BwDown { get; set; }

		[XmlElement("bwUp")]
		public int BwUp { get; set; }

		[XmlElement("latency")]
		public int Latency { get; set; }

		[XmlElement("plr")]
		public int Plr { get; set; }

		[XmlElement("completed")]
		public string Completed { get; set; }

		[XmlElement("runs")]
		public int Runs { get; set; }

		[XmlElement("successfulFVRuns")]
		public int SuccessfulFVRuns { get; set; }

		[XmlElement("successfulRVRuns")]
		public int SuccessfulRVRuns { get; set; }

		[XmlElement("average")]
		public AverageTestResultSet Average { get; set; }

		[XmlElement("run")]
		public List<TestResultSet> TestResultSets { get; set; }
	}

	[Serializable]
	[XmlRoot("average")]
	public class AverageTestResultSet : IBaseTestResultBlock
	{
		[XmlIgnore]
		public IBaseTestViewResult FirstView
		{
			get { return ImplFirstView; }
		}

		[XmlIgnore]
		public IBaseTestViewResult RepeatView
		{
			get { return ImplRepeatView; }
		}

		[XmlElement("firstView")]
		public BaseTestViewResult ImplFirstView { get; set; }

		[XmlElement("repeatView")]
		public BaseTestViewResult ImplRepeatView { get; set; }
	}

	[Serializable]
	public class BaseTestViewResult : IBaseTestViewResult
	{
		[XmlElement("loadTime")]
		public long LoadTime { get; set; }

		[XmlElement("TTFB")]
		public long TTFB { get; set; }

		[XmlElement("bytesIn")]
		public long BytesIn { get; set; }

		[XmlElement("bytesInDoc")]
		public long BytesInDoc { get; set; }

		[XmlElement("requests")]
		public long Requests { get; set; }

		[XmlElement("requestsDoc")]
		public long RequestsDoc { get; set; }

		[XmlElement("render")]
		public long Render { get; set; }

		[XmlElement("fullyLoaded")]
		public long FullyLoaded { get; set; }

		[XmlElement("docTime")]
		public long DocTime { get; set; }

		[XmlElement("domTime")]
		public long DomTime { get; set; }

		[XmlElement("avgRun")]
		public long AvgRun { get; set; }
	}

	[Serializable]
	public class TestResultSet : ITestResultBlock
	{
		[XmlElement("id")]
		public int Id { get; set; }

		[XmlIgnore]
		public ITestViewResult FirstView
		{
			get { return ImplFirstView.Results; }
		}

		[XmlIgnore]
		public ITestViewResult RepeatView
		{
			get { return ImplRepeatView.Results; }
		}

		[XmlIgnore]
		public ITestViewRawData FirstViewRawData
		{
			get { return ImplFirstView.RawData; }
		}

		[XmlIgnore]
		public ITestViewRawData RepeatViewRawData
		{
			get { return ImplRepeatView.RawData; }
		}

		[XmlElement("firstView")]
		public TestViewResultBlock ImplFirstView { get; set; }

		[XmlElement("repeatView")]
		public TestViewResultBlock ImplRepeatView { get; set; }
	}

	[Serializable]
	public class TestViewResultBlock
	{
		[XmlElement("results")]
		public TestViewResult Results { get; set; }

		[XmlElement("rawData")]
		public TestViewRawData RawData { get; set; }
	}

	[Serializable]
	public class TestViewResult : BaseTestViewResult, ITestViewResult
	{
		[XmlElement("URL")]
		public string Url { get; set; }

		[XmlElement("bytesOut")]
		public long BytesOut { get; set; }

		[XmlElement("bytesOutDoc")]
		public long BytesOutDoc { get; set; }

		[XmlElement("connections")]
		public int Connections { get; set; }

		[XmlElement("responses_200")]
		public int Rresponses200 { get; set; }

		[XmlElement("responses_404")]
		public int Responses404 { get; set; }

		[XmlElement("responses_other")]
		public int ResponsesOther { get; set; }

		[XmlElement("result")]
		public int Rresult { get; set; }

		[XmlElement("cached")]
		public bool Cached { get; set; }

		[XmlElement("score_cache")]
		public int ScoreCache { get; set; }

		[XmlElement("score_cdn")]
		public int ScoreCdn { get; set; }

		[XmlElement("score_gzip")]
		public int ScoreGzip { get; set; }

		[XmlElement("score_cookies")]
		public int ScoreCookies { get; set; }

		[XmlElement("score_keep-alive")]
		public int ScoreKeepAlive { get; set; }

		[XmlElement("score_minify")]
		public int ScoreMinify { get; set; }

		[XmlElement("score_combine")]
		public int ScoreCombine { get; set; }

		[XmlElement("score_compress")]
		public int ScoreCompress { get; set; }

		[XmlElement("score_etags")]
		public int ScoreEtags { get; set; }

		[XmlElement("gzip_total")]
		public int GzipTotal { get; set; }

		[XmlElement("gzip_savings")]
		public int GzipSavings { get; set; }

		[XmlElement("minify_total")]
		public int MinifyTotal { get; set; }

		[XmlElement("minify_savings")]
		public int MinifySavings { get; set; }

		[XmlElement("image_total")]
		public int ImageTotal { get; set; }

		[XmlElement("image_savings")]
		public int ImageSavings { get; set; }

		[XmlElement("optimization_checked")]
		public int OptimizationChecked { get; set; }

		[XmlElement("aft")]
		public int Aft { get; set; }

		[XmlElement("domElements")]
		public int DomElements { get; set; }

		[XmlElement("pageSpeedVersion")]
		public string PageSpeedVersion { get; set; }

		[XmlElement("title")]
		public string Title { get; set; }

		[XmlElement("titleTime")]
		public int TitleTime { get; set; }

		[XmlElement("loadEventStart")]
		public int LoadEventStart { get; set; }

		[XmlElement("loadEventEnd")]
		public int LoadEventEnd { get; set; }

		[XmlElement("domContentLoadedEventStart")]
		public int DomContentLoadedEventStart { get; set; }

		[XmlElement("domContentLoadedEventEnd")]
		public int DomContentLoadedEventEnd { get; set; }

		[XmlElement("lastVisualChange")]
		public int LastVisualChange { get; set; }

		[XmlElement("browser_name")]
		public string BrowserName { get; set; }

		[XmlElement("browser_version")]
		public string BrowserVersion { get; set; }

		[XmlElement("server_count")]
		public int ServerCount { get; set; }

		[XmlElement("server_rtt")]
		public int ServerRtt { get; set; }

		[XmlElement("base_page_cdn")]
		public string BasePageCdn { get; set; }

		[XmlIgnore]
		public bool AdultSite
		{
			get { return IntAdultSite.Equals(1); }
		}

		[XmlElement("adult_site")]
		public int IntAdultSite { get; set; }

		[XmlElement("date")]
		public long Date { get; set; }
	}

	[Serializable]
	public class TestViewRawData : ITestViewRawData
	{
		[XmlElement("headers")]
		public string HeadersUrl { get; set; }

		[XmlElement("pageData")]
		public string PageDataUrl { get; set; }

		[XmlElement("requestsData")]
		public string RequestsDataUrl { get; set; }
	}
}